home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-04 / boss_sup.zip / WN_PDOWN.C < prev    next >
C/C++ Source or Header  |  1992-03-05  |  14KB  |  394 lines

  1. /*
  2. ** WN_PDOWN - Pulldown Menu/Window Functions
  3. **
  4. ** Adapted, with permission, from Keith Funk's code.
  5. **
  6. ** Copyright (C) 1992 - Philip A. Mongelluzzo
  7. ** All rights reserved.
  8. **
  9. */
  10.  
  11. #include "winboss.h"                    /* window header */
  12.  
  13. #define ITEM scrn[i]                    /* some short hand */
  14.  
  15. /*
  16. *************
  17. * wn_pdopen *
  18. *************
  19. */
  20.  
  21. /*
  22. ** wn_pdopen(page,row,col,width,height,watr,batr,hkatr,mx,aflag)
  23. */
  24.  
  25. wn_pdopen(page,row,col,width,height,watr,batr,hkatr,mx,aflag)
  26. int page;                               /* video page */
  27. int row, col;                           /* window - upper row/col */
  28. int width, height;                      /* window - height & width */
  29. WNPDPTR mx;                             /* pointer to pulldown menu struct */
  30. int aflag;                              /* active menu items flag */
  31. int watr, batr;                         /* attributes - window & border */
  32. int hkatr;                              /* hot key attribute */
  33. {
  34. int i, ix;                              /* scratch integers */
  35. WINDOWPTR w;                            /* window pointer */
  36.  
  37.   if(!mx->winopn) {                     /* menu not open, open it now */
  38.     mx->lndx = -1;                      /* set index out of range */
  39.     w = wn_open(page, row, col, width, height, watr, batr);
  40.     if (w == NULL) return(FALSE);       /* out of mem or just fubar */
  41.     wn_sync(w,FALSE);                   /* sync cursor */
  42.     mx->wpsave = w;                     /* save pointer */
  43.     mx->wa = watr;                      /* window atrib */
  44.     mx->ba = batr;                      /* border atrib */
  45.     mx->hka = hkatr;                    /* hot key atrib */
  46.     mx->winopn = TRUE;                  /* say window is open */
  47.   }
  48.   else {
  49.     w = mx->wpsave;                     /* fetch window pointer */
  50.     watr = mx->wa;                      /* fetch window atrib */
  51.     hkatr = mx->hka;                    /* fetch hot key atrib */
  52.   }
  53.  
  54. /*
  55. ** For as long as there is data, display it.
  56. **  Use the first active menu item as the initial index.
  57. **    If the item is active then highlight the hot key and remember it.
  58. **    ONLY IF MENU IS ACTIVE
  59. */
  60.  
  61.   i = 0;                                /* init index */
  62.   while(mx->ITEM.r != 99) { 
  63.     wn_putsa(w, mx->ITEM.r, mx->ITEM.c, mx->ITEM.t, watr);
  64.     if(aflag) {
  65.       if(mx->ITEM.status == PDACTIVE) {
  66.         if(mx->lndx == -1) mx->lndx = i;
  67.         ix = wn_cndx(mx->ITEM.t, mx->ITEM.hkc,0);
  68.         wn_putca(w, mx->ITEM.r, mx->ITEM.c+ix, mx->ITEM.hkc, mx->hka);
  69.       }
  70.     }
  71.     i++;
  72.   }
  73.   return(TRUE);
  74. }
  75.  
  76. /*
  77. **************
  78. * wn_pdclose *
  79. **************
  80. */
  81.  
  82. void wn_pdclose(mx)                     /* close pulldown */
  83. WNPDPTR mx;
  84. {
  85.   if(!mx->winopn) return;               /* dont be stupid */
  86.   wn_close(mx->wpsave);
  87.   mx->winopn = FALSE;
  88. }
  89.  
  90.  
  91. /*
  92. ***************
  93. * wn_pdupdate *
  94. ***************
  95. */
  96.  
  97. int wn_pdupdate(mx, i, style)           /* update menu item display */
  98. WNPDPTR mx;                             /* pull down menu struct ptr */
  99. int  i;                                 /* menu item to update */
  100. int  style;                             /* PDNORMAL or PDREVERSE */
  101. {
  102. int watr;                               /* window contents attribute */
  103. int hkatr;                              /* attributes for hotkey */
  104. int atr;                                /* atrib that will be used */
  105. int hklite;                             /* hotkey highlight attrib */
  106. WINDOWPTR w;                            /* window pointer */
  107. int ix;                                 /* hot key char index */
  108.  
  109.   if (!mx->winopn) return(FALSE);       /* window isn't open */
  110.  
  111.   w = mx->wpsave;                       /* fetch window ptr */
  112.   watr = mx->wa;                        /* and misc atributes */
  113.   hkatr = mx->hka;                      /* .... */
  114.  
  115.   if (style == PDREVERSE)               /* use reverse video */
  116.   {
  117.     atr = v_setrev(watr);               /* make reverse atrib for line */
  118.     hklite = ((hkatr & 0x0F) | (~watr & 0x70)); /* form new hotkey atrib */
  119.   }
  120.   else                                  /* normal video */
  121.   {
  122.     atr = watr;                         /* right from the structure */
  123.     hklite = hkatr;                     /* as it was opened */
  124.   }
  125.  
  126.   wn_putsa(w, mx->ITEM.r, mx->ITEM.c, mx->ITEM.t, atr);
  127.  
  128.   if (mx->ITEM.status == PDACTIVE) {    /* display hot key */
  129.     ix = wn_cndx(mx->ITEM.t, mx->ITEM.hkc,0);
  130.     wn_putca(w, mx->ITEM.r, mx->ITEM.c + ix, mx->ITEM.hkc, hklite);
  131.   }
  132.   return(TRUE);
  133. }
  134.  
  135. #ifdef COMMENTS
  136. /*
  137. ***************
  138. * wn_pdsettog *                         /* set toggle */
  139. ***************
  140. */
  141. #endif
  142.  
  143. wn_pdsettog(mx, i)                      /* reverse state of togle */
  144. WNPDPTR mx;                             /* menu pointer */
  145. int i;                                  /* menu item of interest */
  146. {
  147. int j, k;                               /* scratch intergers */
  148.  
  149.   if((mx->ITEM.type != 'T')  && (mx->ITEM.type != 'E'))
  150.     return(PDTOGOK);                    /* no toggles active */
  151.   if (*(mx->ITEM.t) == '√')             /* toggle is ON, so turn it OFF. */
  152.   {
  153.     *(mx->ITEM.t) = ' ';                /* by loading a blank */
  154.     return(PDTOGOK);                    /* then return */
  155.   }
  156.   
  157.   *(mx->ITEM.t) = '√';                  /* toggle is off so turn it on */
  158.   if(mx->ITEM.type == 'T')              /* exclusive toggle ?? */
  159.     return(PDTOGOK);                    /* no... simply return */
  160.  
  161.   k = -2;                               /* set index mark */
  162.  
  163.   for (j = mx->fm; j <= mx->lm; j++) {  /* turn all other toggles OFF */
  164.     if ((j != i) && (mx->scrn[j].type != 'S')) {
  165.       if (*(mx->scrn[j].t) == '√') {   /* was ON, so save its index */
  166.         k = j;
  167.         *(mx->scrn[j].t) = ' ';
  168.       }
  169.     }
  170.   }
  171.   if(k == -2)                           /* no other toggles were on */
  172.     return(PDTOGOK);                    /* so say all went well */
  173.   else
  174.     return(k);                          /* ret index of previous ON toggle */
  175. }
  176.  
  177. /*
  178. ***************
  179. * wn_pdgettog *
  180. ***************
  181. */
  182.  
  183. wn_pdgettog(mx, i)                      /* get toggle */
  184. WNPDPTR mx;                             /* menu pointer */
  185. int i;                                  /* RETURN val of menu item of interest */
  186. {                                       /* -1 sez look for any ON toggle */
  187. int j;                                  /* scratch integer */
  188.  
  189.   if (i != -1)                          /* get status of specific toggle */
  190.   {
  191.     for (j = mx->fm; j <= mx->lm; j++)  /* find the toggle by its return code */
  192.       if (mx->scrn[j].rv == i) break;
  193.     if (*(mx->scrn[j].t) == '√')        /* ALT-251, toggle is ON */
  194.       return(TRUE);
  195.     else
  196.       return(FALSE);
  197.   }
  198.   else                                  /* find out if any toggle is ON */
  199.   {
  200.     for (j = mx->fm; j <= mx->lm; j++)
  201.       if (*(mx->scrn[j].t) == '√')      /* ALT-251, toggle is ON */
  202.         return(mx->scrn[j].rv);         /* return toggles rv code */
  203.   }
  204.   return(PDTOGOK);                      /* no toggles are ON */
  205. }
  206.  
  207.  
  208. /*
  209. ***************
  210. * wn_pdactive *
  211. ***************
  212. */
  213.  
  214. void wn_pdactive(mx, i, action)         /* menu activate/deactivate */
  215. WNPDPTR mx;                             /* pointer to menu structure. */
  216. int i;                                  /* menu item's RETURN code */
  217. int action;                             /* TRUE=activate, FALSE=de-activate */
  218. {
  219. int j;                                  /* scratch integer */
  220.  
  221.   for (j = mx->fm; j <= mx->lm; j++)    /* look up item via RETURN code */
  222.     if (mx->scrn[j].rv == i) break;
  223.  
  224.   if(action == TRUE)
  225.     mx->scrn[j].status = PDACTIVE;
  226.   else
  227.     mx->scrn[j].status = PDINACTIVE;
  228. }
  229.  
  230. /*
  231. *************
  232. * wn_pdtype *
  233. *************
  234. */
  235.  
  236. int  wn_pdtype(mx, i, newtype, action)
  237. WNPDPTR mx;                             /* pointer to menu structure. */
  238. int i;                                  /* menu item RETURN code */
  239. char newtype;                           /* ignored if Action is FALSE */
  240. int action;                             /* TRUE or FALSE */
  241. {
  242. int j;                                  /* scratch integer */
  243.  
  244.   for (j = mx->fm; j <= mx->lm; j++)    /* lookup via return code */
  245.     if (mx->scrn[j].rv == i) break;
  246.  
  247.   if (action == TRUE)                   /* set a new type */
  248.     mx->scrn[j].type = newtype;
  249.   else
  250.     return (mx->scrn[j].type);          /* return current type */
  251.   return(FALSE);
  252. }
  253.  
  254. /*
  255. ************
  256. * wn_pdget *
  257. ************
  258. */
  259.  
  260. int wn_pdget(mx)
  261. WNPDPTR mx;                             /* pointer to popup menu struct */
  262. {
  263. int i;                                  /* scratch integer */
  264. unsigned int c;                         /* key scan code,,char */
  265. int j;                                  /* 1st char scan index */
  266. char ch;                                /* CHARACTER (!scan code) Entered */
  267. char ch1, ch2;                          /* for caseless searching */
  268. int barmenu;                            /* holds menu type */
  269.  
  270.   if (!mx->winopn)                      /* avoid foolishness */
  271.     return(-1);                         /* make sure menu is open */
  272.  
  273.   i = mx->lndx;                         /* and index of last menu item */
  274.  
  275. /*
  276. ** If first and last menu items are on the same row then its a BARMENU
  277. */
  278.  
  279.   if (mx->scrn[mx->fm].r == mx->scrn[mx->lm].r)
  280.     barmenu = TRUE;
  281.   else
  282.     barmenu = FALSE;
  283.  
  284.   while(TRUE)                           /* exit via RET or hotkey */
  285.   {
  286.     if (mx->scrn[i].status == PDACTIVE) /* option is active, so display */
  287.       wn_pdupdate(mx, i, PDREVERSE);    /* in reverse video */
  288.  
  289.     c = v_getch();                      /* Fetch char and scan code */
  290.     ch = c & 0x7F;                      /* extract character */
  291.  
  292.     if(c == ESCAPE) break;              /* ESC (user wants out) */
  293.     if((!barmenu) && ((c==LARROW) || (c==RARROW)))
  294.       break;                            /* user wants out of pulldown menu */
  295.  
  296.     if (mx->scrn[i].status != PDACTIVE) /* no active options in the menu, so */
  297.       continue;                         /* only EXIT type keys are valid */
  298.  
  299. /*
  300. ** CASE 1 - RETURN or DOWN ARROW Pressed (on barmenu)
  301. **          Select & Exit
  302. */
  303.  
  304.     if ((c == RETurn) || (barmenu && (c == DARROW)))
  305.     {                                   /* Non toggle type */
  306.       if ((mx->scrn[i].type != 'T') && (mx->scrn[i].type != 'E'))
  307.       {
  308.         mx->lndx = i;                   /* save option index */
  309.         return(mx->scrn[i].rv);         /* exit */
  310.       }
  311.       else                              /* is a toggle, so don't exit */
  312.       {                                 /* reverse the toggle state */
  313.         j = wn_pdsettog(mx, i);         /* if they are Exclusive toggles */
  314.         if (j != PDTOGOK)               /* and another toggle was ON */
  315.           wn_pdupdate(mx, j, PDNORMAL); /* j has its index, update display*/
  316.       }
  317.     }
  318.  
  319. /*
  320. ** CASE 2 - On a Barmenu and Right Arrow Pressed or
  321. **          On a drop menu and Down Arrow Pressed
  322. **          On a Barmenu and Left Arrow Pressed or
  323. **          On a drop menu and Up Arrow Pressed
  324. */
  325.  
  326.     if((barmenu && (c == RARROW)) || (!barmenu && (c == DARROW)))
  327.     {
  328.       j = i + 1;                        /* find next active option */
  329.       while (TRUE)
  330.       {
  331.         if (j > mx->lm) j = mx->fm;     /* wrap at end */
  332.         if (mx->scrn[j].status == PDACTIVE) break; /* active option found */
  333.         if (j == i) break;              /* no active menu options */
  334.         j++;
  335.       }
  336.       if (j != i)                       /* found a diff  active option*/
  337.         wn_pdupdate(mx, i, PDNORMAL);   /* unmark old choice. */
  338.       i = j;                            /* bump index */
  339.     }
  340.     else if ((barmenu && (c == LARROW)) || (!barmenu && (c == UARROW)))
  341.     {
  342.       j = i - 1;                        /* find previous active option */
  343.       while (TRUE)
  344.       {
  345.         if (j < mx->fm) j = mx->lm;     /* wrap at end */
  346.         if (mx->scrn[j].status == PDACTIVE) break; /* active option found */
  347.         if (j == i) break;              /* no active options */
  348.         j--;
  349.       }
  350.       if (j != i)                       /* found a diff  active option*/
  351.         wn_pdupdate(mx, i, PDNORMAL);   /* unmark old choice */
  352.       i = j;                            /* bump index */
  353.     }
  354.  
  355. /*
  356. ** CASE 3 - Hot Key Pressed
  357. */
  358.     for (j = mx->fm; j <= mx->lm; j++)  /* Search for match */
  359.     {
  360.       ch1 = toupper(ch);
  361.       ch2 = toupper(mx->scrn[j].hkc);
  362.       if ((ch1 == ch2) && (mx->scrn[j].status == PDACTIVE))
  363.       {
  364.        wn_pdupdate(mx, i, PDNORMAL);    /* unmark old choice */
  365.  
  366.                                         /* IF TOGGLE then... */
  367.        if ((mx->scrn[j].type == 'T') || (mx->scrn[j].type == 'E'))
  368.         i = wn_pdsettog(mx, j);         /* switch toggle */
  369.        if (i != PDTOGOK)                /* if other exclusive toggle */
  370.           wn_pdupdate(mx, i, PDNORMAL); /* was ON, redisplay as OFF */
  371.        i = j;                           /* set new choice */
  372.  
  373.                                         /* IF NOT TOGGLE then... */
  374.        if ((mx->scrn[i].type != 'T') && (mx->scrn[i].type != 'E'))
  375.        {
  376.          wn_pdupdate(mx, i, PDREVERSE); /* hilight new choice */
  377.          mx->lndx = i;                  /* remember last indx */
  378.          return(mx->scrn[i].rv);        /* return with rv */
  379.        }
  380.        else
  381.          break;                         /* don't EXIT on a toggle */
  382.       }
  383.     }                                   /* end hotkey scan loop */
  384.   }                                     /* end while */
  385.  
  386.   wn_pdclose(mx);                       /* CLOSE the menu */
  387.  
  388.   if (c==LARROW) return(97);            /* Set return code */
  389.   if (c==RARROW) return(98);
  390.   return(99); 
  391. }
  392.  
  393. /* End */
  394.